package com.heartunderblade.rpc.observer;

import org.redisson.api.RMap;
import org.redisson.api.RMapCache;
import org.redisson.api.listener.MapPutListener;
import org.redisson.api.listener.MapRemoveListener;
import org.redisson.api.map.event.EntryEvent;
import org.redisson.api.map.event.EntryRemovedListener;
import org.redisson.api.map.event.EntryUpdatedListener;

import java.util.ArrayList;
import java.util.List;

/**
 * 监听redis变更并且通知观察者核心部分，监听RMap，通知Listener
 */
public class MapSubject {
    private final RMapCache<String ,String> map;
    private final String serviceKey;
    private final List<Listener> listeners = new ArrayList<>();

    public MapSubject(RMapCache<String, String> map, String serviceKey) {
        this.map = map;
        this.serviceKey = serviceKey;
    }

    /**
     * 注册监听器
     * @param listener
     */
    public void addListener(Listener listener) {
        listeners.add(listener);
    }

    /**
     * 移除监听器
     * @param listener
     */
    public void removeListener(Listener listener) {
        listeners.remove(listener);
    }

    /**
     * 通知所有的监听器
     * @param event
     */
    private void notifyListeners(MapEvent event){
        for (Listener listener : listeners) {
            switch (event.getEventType()) {
                case CREATED:
                    listener.onCreated(event);
                    break;
                case REMOVED:
                    listener.onRemoved(event);
                    break;
            }
        }
    }
    public void startListening(){
        // CREATED 事件监听

        map.addListener(new EntryUpdatedListener<String, String>() {
            @Override
            public void onUpdated(EntryEvent<String, String> event) {
                MapEvent update = new MapEvent(event.getKey(),MapEvent.EventType.CREATED);
                notifyListeners(update);
                System.out.println("Key updated: " + event.getKey());
                System.out.println("Old value: " + event.getOldValue());
                System.out.println("New value: " + event.getValue());
            }
        });
        map.addListener(new EntryRemovedListener<String, String>() {
            @Override
            public void onRemoved(EntryEvent<String, String> event) {
                MapEvent remove = new MapEvent(event.getKey(),MapEvent.EventType.REMOVED);
                notifyListeners(remove);
                System.out.println("Key removed: " + event.getKey());
                System.out.println("Value: " + event.getValue());
            }
        });

    }

}
